﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Pacman.Simulator
{
    class PowerPelletController
    {
        private PowerPellet[] powerPellets = new PowerPellet[4];
        float beta;
        GameState gameState;
        int numPellets;

        public PowerPelletController(GameState gs)
        {
            gameState = gs;
            numPellets = 0;
        }

        //order of addition determines index value
        //for powerPellet retrieval.
        public void addPowerPellet(Node node)
        {
            if (numPellets < 4)
            {
                powerPellets[numPellets++] = new PowerPellet(node);
            }
        }


        //calculate and set the average distance between each ghost 
        protected void setBeta()
        {
            float d01, d02, d03, d12, d13, d23;
            d01 = gameState.Ghosts[0].Distance(gameState.Ghosts[1]);
            d02 = gameState.Ghosts[0].Distance(gameState.Ghosts[2]);
            d03 = gameState.Ghosts[0].Distance(gameState.Ghosts[3]);
            d12 = gameState.Ghosts[1].Distance(gameState.Ghosts[2]);
            d13 = gameState.Ghosts[1].Distance(gameState.Ghosts[3]);
            d23 = gameState.Ghosts[2].Distance(gameState.Ghosts[3]);
            beta = (d01 + d02 + d03 + d12 + d13 + d23) / 6;
        }

        //determine if a powerpellet is in a solution state
        //for the ghost grouping problem.
        public bool evaluatePowerPellet(int index, float t = 1.0f)
        {
            float a, q, g, s;

            if (index >= numPellets || index < 0)
            {
                return false;
            }
            else
            {
                setBeta();
                a = powerPellets[index].getAlpha(gameState);

                //ghost fleeSpeed == 1.5f and nodes 
                //are 8.0f across
                //g == ghost speed in iterations per position
                g = 8.0f / 1.5f;

                //Ms Pac-man speed is 3.0f and 
                //nodes are 8.0f across
                //s == Ms Pac-man speed in iterations per position
                s = 8.0f / 3.0f;

                //fleeLength in iterations
                //at 66.67f ms per frame
                //is 4000 / 66.67
                q = 4000.0f/66.6f; //rounded down to be conservative

                //t == 1.0f default
                // if we want the condition to relax 
                //as we progress through the level 
                //we can make t = remainingDots/totalDots
                //which is the percentage of dots remaining
                //where the value will relax as we eat dots.
              

                if (t * a < ((q * (g - s)) / (1 + beta)))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        //gets the power-pellet nearest Ms Pac-man
        public int getNearestPowerPellet()
        {
            int nearest = 0;
            for (int i = 0; i < numPellets; i++)
            {

                if (powerPellets[i].getDistance(gameState) < powerPellets[nearest].getDistance(gameState))
                {
                    nearest = i;
                }

            }

            return nearest;
        }

        //helper class to hold specific power pellets
        //for the PowerPelletController class. 
        class PowerPellet
        {
            float alpha;
            Node node;

            public PowerPellet(Node n)
            {
                node = n;
            }

            //calculate the average ghost distance from this power-pellet
            public void setAlpha(GameState gameState)
            {
                float x, y, d1, d2, d3, d4;
                x = (float)node.X;
                y = (float)node.Y;
                d1 = (float)Math.Sqrt(Math.Pow(x - gameState.Ghosts[0].X, 2) + Math.Pow(y - gameState.Ghosts[0].Y, 2));
                d2 = (float)Math.Sqrt(Math.Pow(x - gameState.Ghosts[1].X, 2) + Math.Pow(y - gameState.Ghosts[1].Y, 2));
                d3 = (float)Math.Sqrt(Math.Pow(x - gameState.Ghosts[2].X, 2) + Math.Pow(y - gameState.Ghosts[2].Y, 2));
                d4 = (float)Math.Sqrt(Math.Pow(x - gameState.Ghosts[3].X, 2) + Math.Pow(y - gameState.Ghosts[3].Y, 2));
                alpha = (d1 + d2 + d3 + d4) / 4;
            }

            public float getAlpha(GameState gs)
            {
                setAlpha(gs);
                return alpha;
            }

            //get Ms Pac-man's distance fromt his power pellet
            public float getDistance(GameState gs)
            {
                float x = (float)node.X;
                float y = (float)node.Y;
                return (float)Math.Sqrt(Math.Pow(x - gs.Pacman.X, 2) + Math.Pow(y - gs.Pacman.Y, 2));


            }
        }
    }
}
